home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
UTILITY
/
TSRSRC34.ARJ
/
MARK.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-02-14
|
11KB
|
294 lines
;==============================================================================
; MARK.ASM - mark a position in memory,
; above which TSRs will later be cleared by RELEASE
; MARK can be called multiple times, each RELEASE will clear
; above the last MARK called.
; If MARK is called with something on the command line, that text will
; be stored in the program segment prefix at offset 80H, where it is
; later accessible to RELEASE for a "named" release.
;
; Syntax: MARK [/Q] [!][MarkName]
;==============================================================================
; written for TASM
; Copyright (c) 1986,1991 Kim Kokkonen, TurboPower Software.
; May be freely distributed but not sold except by permission.
; telephone: 719-260-6641, Compuserve 76004,2611
;==============================================================================
; version 1.0 2/8/86
; original public release
; (thanks to Neil Rubenking for an outline of the method used)
; :
; long intervening history
; :
; version 3.0 9/24/91
; add Quiet option
; add code for tracking high memory
; version 3.1 11/4/91
; no change
; version 3.2 11/22/91
; change method of accessing high memory
; store parent len as well as parent segment
; version 3.3 1/8/92
; no change
; version 3.4 2/14/92
; no change
;==============================================================================
Cseg segment public para
assume cs:Cseg, ds:Cseg, es:nothing
locals @@
org 81H
cmdlin label byte ;first character of command line
org 100H
comentry: jmp doit
;put the following in the MAP file
public idstr,vector,egasav,intcom,emscnt,emsmap
idstr db 'MM3.4 TSR' ;used to find this TSR
firsthimcb dw 0 ;segment of first mcb in high mem
;**** the following will be overwritten by the vector table image *************
;success message and version number
didit db 'MARK 3.4, Copyright 1991 TurboPower Software',13,10
didit2 db 'Marked current memory position',13,10,36
errst db 'Invalid command line',13,10,36
;file name for testing EMS presence
emsnm db 'EMMXXXX0',0
quiet db 0
xmsadr label dword ;XMS control address
xmsxxx dw 2 dup (0)
;******************************************************************************
vector equ 0120H ;offset in code seg where vector table is copied
veclen equ 0400H ;1024 bytes for vectors
egasav equ vector+veclen
egalen equ 8 ;8 bytes for EGA save area
intcom equ egasav+egalen
intlen equ 10H ;16 bytes for interapps communication area
parent equ intcom+intlen
parlen equ parent+2 ;parent's PSP length
emscnt equ parlen+2
emsmap equ emscnt+2
;mcbcnt and mcbmap actually follow after used portion of emsmap
mcbcnt equ emsmap+400H ;count of allocated mcbs
mcbmap equ mcbcnt+2 ;array of mcb segments
;newloc follows after the longest possible emsmap and mcbmap
newloc equ mcbmap+400H ;location of relocated code
;*****************************************************************************
doit proc near
;find first mcb in high memory, if any
mov ax,3000h ;get DOS version
int 21H
cmp al,3
jb @@7 ;no XMS driver possible
mov ax,4300h
int 2Fh ;multiplex call for XMS
cmp al,80h ;proper signature?
jne @@7 ;no XMS driver
mov ax,4310h ;get XMS control address
int 2Fh
mov xmsxxx,bx ;save it
mov xmsxxx[2],es
mov ah,10h
mov dx,0FFFFh
call xmsadr ;ask to allocate FFFF paras of UMB
cmp bl,0B0h ;will fail with B0 if UMBs avail
je @@0
cmp bl,0B1h ;will fail with B1 if UMBs all allocated
jne @@7 ;no UMBs exist
@@0: int 12H
mov cl,6
shl ax,cl ;get segment of top of memory
@@1: mov es,ax
cmp byte ptr es:[0000h],'M' ;potential mcb?
jnz @@6 ;not an mcb, try next segment
@@2: mov cx,ax ;save potential start mcb in cx
@@3: inc ax
add ax,es:[0003h] ;ax = start of next mcb
jc @@5 ;can't be an mcb if we wrapped
mov es,ax ;address of next mcb
mov dl,es:[0000h]
cmp dl,'M'
jz @@3 ;good start mcb
cmp dl,'Z'
jz @@9 ;good end mcb
@@5: mov ax,cx ;restore last start segment
@@6: cmp ax,0FFFFh ;top of memory?
je @@7
inc ax ;try next segment
jmp @@1
@@7: xor cx,cx ;no matching UMB
@@9: mov firsthimcb,cx ;store first high mcb
;relocate ourselves out of the way
push cs
pop es
mov di,newloc
push di ;will act as a return address
mov si,offset parse
mov cx,lastcode-parse
cld
rep movsb
ret ;"return" to the relocated code
;scan command line for /Q option
parse: mov si,offset cmdlin
cld
get1: lodsb
cmp al,13 ;end of command line?
je pmess
cmp al,'/' ;option switch?
je getop
cmp al,'-'
jne get1 ;loop around
getop: mov di,si ;save option position
lodsb
cmp al,'a'
jb noup
cmp al,'z'
ja noup
and al,0DFH ;uppercase
noup: cmp al,'Q'
jne error
mov quiet,1 ;set quiet flag
dec di
mov al,' '
stosb ;clear option
stosb
jmp get1 ;loop around
error: mov dx,offset errst
mov ah,9
int 21H
mov ax,4C01H
int 21H
;print message if not quiet
pmess: cmp quiet,0
jnz chkems
mov dx,offset didit
mov ah,9
int 21H ;write success message
;determine whether EMS is present
chkems: mov dx,offset emsnm
mov ax,3D00H
int 21H
jnc emspres ;EMS driver installed
xor bx,bx
jmp short stocnt
;EMS present, close the open handle first
emspres:
mov bx,ax
mov ah,3EH
int 21H
;store the EMS page map
mov ah,4DH
mov di,emsmap
xor bx,bx ;required by some versions of EMM
cld ;required by some versions of EMM
int 67H
;store the number of active EMS handles
stocnt:
mov ds:[emscnt],bx ;count of active handles
;store the interrupt vector table (overwrites initial messages)
xor ax,ax
mov ds,ax ;source address segment 0
assume ds:nothing
xor si,si ;offset 0
mov di,vector ;destination offset, es=cs already
mov cx,veclen shr 1 ;count of words to store
rep movsw ;copy vectors to our table
;store the EGA save area
mov ax,40H
mov ds,ax ;point to BIOS data area
mov si,00A8H ;EGA save area pointer
mov di,egasav
mov cx,egalen shr 1
rep movsw ;copy information to our save area
;store the interapplications communication area
mov si,00F0H ;interapps communication area address
mov di,intcom
mov cx,intlen shr 1
rep movsw ;copy information to our save area
;store the parent's PSP segment
push cs
pop ds ;ds = cs
assume ds:cseg
mov ax,ds:[16h] ;get parent's PSP from our PSP
mov ds:[parent],ax ;store in data save area
dec ax
mov es,ax
mov ax,es:[0003h] ;get length of parent's psp
mov ds:[parlen],ax ;store in data save area
;store the mcb chain
mov ah,52H ;get first mcb segment
int 21H
mov ax,es:[bx-2] ;ax=first mcb
push cs
pop es ;es=cs
mov di,cs:[emscnt] ;get starting address of mcbmap
shl di,1
shl di,1
add di,emsmap
mov si,di ;cs:[si] -> mcbcnt
add di,2 ;cs:[di] -> mcbmap
xor cx,cx ;cx will count mcbs
cld
push ds
assume ds:nothing
mcbnext:
stosw ;store mcb segment held by ax
mov ds,ax ;ds:[0] points to mcb
mov ax,ds:[1] ;get mcb owner
stosw ;store it
inc cx ;increment count
cmp byte ptr ds:[0],'Z' ;end of mcb chain?
je mcbdone
mov ax,ds ;restore ax to mcb segment
inc ax ;skip over mcb itself
add ax,ds:[3] ;add length of memory block
jmp mcbnext
mcbdone:mov ax,firsthimcb ;check for high memory
or ax,ax
jz mcbend
mov firsthimcb,0 ;only do it once
jmp mcbnext
mcbend: pop ds
assume ds:cseg
;terminate and stay resident
gores: mov [si],cx ;store mcbcnt
mov dx,di ;dx = past last used mcb segment
add dx,000FH ;add paragraph roundup
mov cl,4
shr dx,cl ;convert to paragraphs
mov ax,3100H
int 21H ;terminate but stay resident
lastcode:
doit endp
Cseg ends
end ComEntry